#define MAINMENU_CPP
/*************************************************************************************************\
MainMenu.cpp			: Implementation of the MainMenu component.
//---------------------------------------------------------------------------//
// Copyright (C) Microsoft Corporation. All rights reserved.                 //
//===========================================================================//
\*************************************************************************************************/

#include <windows.h>
#include <ddraw.h>
#include "MainMenu.h"
#include "McLIb.h"
#include "iniFile.h"
#include "LogisticsData.h"
#include "LogisticsDialog.h"
#include "aButton.h"
#include "OptionsScreenWrapper.h"
#include <windows.h>
#include "..\resource.h"
#include "mechlopedia.h"
#include "gameSound.h"
#include "aAnimObject.h"
#include "Multplyr.h"

#include "prefs.h"
extern CPrefs prefs;


#define MM_MSG_NEW_CAMPAIGN 90
#define MM_MSG_SAVE			92
#define MM_MSG_LOAD			91
#define MM_MSG_MULTIPLAYER	93
#define MM_MSG_RETURN_TO_GAME 94
#define MM_MSG_OPTIONS		95
#define MM_MSG_ENCYCLOPEDIA	96
#define MM_MSG_EXIT			97
#define MM_MSG_SINGLE_MISSION	98
#define MM_MSG_LEGAL		99

extern volatile bool mc2IsInMouseTimer;
extern volatile bool mc2IsInDisplayBackBuffer;

void MouseTimerKill();

extern void (*AsynFunc)(RECT& WinRect,DDSURFACEDESC2& mouseSurfaceDesc );




extern bool bInvokeOptionsScreenFlag;
bool	MainMenu::bDrawMechlopedia = false;;

void SplashIntro::init()
{
	FullPathFileName path;
	path.init( artPath, "mcl_splashscreenintro", ".fit" );

	FitIniFile file;
	if ( NO_ERR != file.open( path ) )
	{
		char errorStr[256];
		sprintf( errorStr, "couldn't open file %s", (char*)path );
		Assert(0,0,errorStr );
	}

	LogisticsScreen::init( file, "Static", "Text", "Rect", "Button" );
}

MainMenu::MainMenu(  )
{
	optionsScreenWrapper = NULL;
	bOptions = 0;
	bSave = bLoad = 0;
	helpTextArrayID = 0;
	mechlopedia = 0;
	bDrawMechlopedia = 0;
	tuneId = -1;
	bLoadSingle = 0; 
	bLoadCampaign = 0;
	introOver = 0;
	bHostLeftDlg = 0;

	introMovie = 0;
}

//-------------------------------------------------------------------------------------------------

MainMenu::~MainMenu()
{
	if ( optionsScreenWrapper )
		delete optionsScreenWrapper;
}

int MainMenu::init( FitIniFile& file )
{
	file.seekBlock("Tunes");
	file.readIdLong("TuneId",tuneId);

	LogisticsScreen::init( file, "Static", "Text", "Rect", "Button" );

	FullPathFileName name;
	name.init( artPath, "mcl_sp", ".fit" );
	FitIniFile file2;
	if ( NO_ERR != file2.open( name ) )
	{
		char errorStr[256];
		sprintf( errorStr, "couldn't open file %s", (char*)name );
		Assert(0,0,errorStr );
	}

	background.init( file2, "Static", "Text", "Rect", "Button" );

	for ( int i = 0; i < buttonCount; i++ )
	{
		buttons[i].setMessageOnRelease();
		buttons[i].setPressFX(LOG_VIDEOBUTTONS);
		buttons[i].setHighlightFX(LOG_DIGITALHIGHLIGHT);
	}

	beginAnim.initWithBlockName( &file, "InAnim" );
	endAnim.initWithBlockName( &file, "OutAnim" );


	intro.init();

	FullPathFileName path;
	path.init( artPath, "mcl_mp_loadmap", ".fit" );

	FitIniFile mpFile;

	if ( NO_ERR != mpFile.open( path ) )
	{
		char error[256];
		sprintf( error, "couldn't open file %s", path );
		Assert( 0, 0, error );
		return -1;		
	}

	singleLoadDlg.init( &mpFile );

	introMovie = 0;

	path.init( moviePath, "msft", ".bik" );

	RECT movieRect;
	movieRect.top = 0;
	movieRect.left = 0;
	movieRect.right = Environment.screenWidth;
	movieRect.bottom = Environment.screenHeight;

	introMovie = new MC2Movie;
	introMovie->init(path,movieRect,true);

	return 0;
}

void MainMenu::begin()
{
	status = RUNNING;
	promptToQuit = 0;
	beginAnim.begin();
	beginFadeIn( 0 );
	endAnim.end();
	background.beginFadeIn( 0 );
	endResult = RUNNING;
	musicStarted = false;
	bLoadSingle = 0;
	bLoadCampaign = 0;
	promptToDisconnect = 0; 
	bLegal = 0;

	// no host left dlg, sometimes we get this begin call 2x's due to netlib weirdness
	if ( !introMovie )
	{
			while (mc2IsInMouseTimer)
				;

			//ONLY set the mouse BLT data at the end of each update.  NO MORE FLICKERING THEN!!!
			// BLOCK THREAD WHILE THIS IS HAPPENING
			mc2IsInDisplayBackBuffer = true;

			mc2UseAsyncMouse = prefs.asyncMouse;
			if ( !mc2UseAsyncMouse)
				MouseTimerKill();

			mc2IsInDisplayBackBuffer = false;

			AsynFunc = NULL;

			//Force mouse Cursors to smaller or larger depending on new video mode.
			userInput->initMouseCursors("cursors");
			userInput->mouseOn();
			userInput->setMouseCursor( mState_LOGISTICS );

			DWORD localRenderer = prefs.renderer;
			if (prefs.renderer != 0 && prefs.renderer != 3)
				localRenderer = 0;

   			bool localFullScreen = prefs.fullScreen;
   			bool localWindow = !prefs.fullScreen;
   			if (Environment.fullScreen && prefs.fullScreen)
   				localFullScreen = false;


			// make sure we get into 800 x 600 mode
			if ( Environment.screenWidth != 800 )
			{
			
				if (prefs.renderer == 3)
					gos_SetScreenMode(800,600,16,0,0,0,true,localFullScreen,0,localWindow,0,localRenderer);
				else
					gos_SetScreenMode(800,600,16,prefs.renderer,0,0,0,localFullScreen ,0,localWindow,0,localRenderer);
			}


	}
}

void MainMenu::end()
{
	endAnim.end();
	bHostLeftDlg = 0;

}

void MainMenu::setDrawBackground( bool bNewDrawBackground )
{
	bDrawBackground = bNewDrawBackground;
	if ( bDrawBackground && !introOver)
	{
		intro.begin();
	}
}

int	MainMenu::handleMessage( unsigned long what, unsigned long who )
{
	switch ( who )
	{
		case MM_MSG_NEW_CAMPAIGN:
			if ( MPlayer )
			{
				LogisticsOKDialog::instance()->setText( IDS_PROMPT_TO_DISCONNECT, IDS_DIALOG_NO, IDS_DIALOG_YES );
				LogisticsOKDialog::instance()->begin();
				endResult = MM_MSG_NEW_CAMPAIGN;
				promptToDisconnect = true;
			}
			else
			{
				endAnim.begin();
				beginAnim.end();
				bLoadCampaign = true;
				LogisticsSaveDialog::instance()->beginCampaign();
				if ( LogisticsSaveDialog::instance()->isDone() )
				{
					LogisticsData::instance->startNewCampaign( LogisticsSaveDialog::instance()->getFileName());
					status = RESTART;
				}
			}
			break;
		case MM_MSG_SAVE:
			if ( MPlayer )
			{
				LogisticsOKDialog::instance()->setText( IDS_PROMPT_TO_DISCONNECT, IDS_DIALOG_NO, IDS_DIALOG_YES );
				LogisticsOKDialog::instance()->begin();
				endResult = who;
				promptToDisconnect = true;
			}
			else
			{
		
				// need to pop dialog here
				LogisticsSaveDialog::instance()->begin();
				endAnim.begin();
				beginAnim.end();
				bSave = true;
			}
			break;

		case MM_MSG_LOAD:

			if ( MPlayer )
			{
				LogisticsOKDialog::instance()->setText( IDS_PROMPT_TO_DISCONNECT, IDS_DIALOG_NO, IDS_DIALOG_YES );
				LogisticsOKDialog::instance()->begin();
				endResult = who;
				promptToDisconnect = true;
			}
			else
			{
			
				// need to pop dialog here
				LogisticsSaveDialog::instance()->beginLoad();
				endAnim.begin();
				beginAnim.end();
				bLoad = true;
			}
			break;
		case MM_MSG_MULTIPLAYER:
			if ( MPlayer )
			{
				LogisticsOKDialog::instance()->setText( IDS_PROMPT_TO_DISCONNECT, IDS_DIALOG_NO, IDS_DIALOG_YES );
				LogisticsOKDialog::instance()->begin();
				endResult = who;
				promptToDisconnect = true;
			}
			else
			{
				endAnim.begin();
				beginAnim.end();
				endResult = MULTIPLAYERRESTART;
				LogisticsData::instance->startMultiPlayer();
			}
			break;

		case MM_MSG_RETURN_TO_GAME:
			{
			if ( !bDrawBackground )
			{
				endAnim.begin();
				beginAnim.end();
				endResult = NEXT;
				soundSystem->playDigitalSample( LOG_MAINMENUBUTTON );
				soundSystem->playDigitalMusic(LogisticsData::instance->getCurrentMissionTune());
			}
			}
			break;
		case MM_MSG_OPTIONS:
			// need to throw up the options screen here...
			if (!optionsScreenWrapper)
			{
				optionsScreenWrapper = new OptionsScreenWrapper;
				optionsScreenWrapper->init();
			}
			optionsScreenWrapper->begin();

			bOptions = true;
			break;
		case MM_MSG_ENCYCLOPEDIA:
			bDrawMechlopedia = true;
			beginFadeOut(1.0);
			if ( !mechlopedia )
			{
				mechlopedia = new Mechlopedia;
				mechlopedia->init();
			}

			mechlopedia->begin();
			break;
		case MM_MSG_EXIT:
			promptToQuit = 1;
			// may need to set the text here
			LogisticsOKDialog::instance()->setText( IDS_DIALOG_QUIT_PROMPT,
					IDS_DIALOG_NO, IDS_DIALOG_YES );
				
			LogisticsOKDialog::instance()->begin();
			getButton( who )->press( 0 );
			break;

		case MM_MSG_SINGLE_MISSION:

			if ( MPlayer )
			{
				LogisticsOKDialog::instance()->setText( IDS_PROMPT_TO_DISCONNECT, IDS_DIALOG_NO, IDS_DIALOG_YES );
				LogisticsOKDialog::instance()->begin();
				endResult = who;
				promptToDisconnect = true;
			}
			else
			{
				bLoadSingle = true;
				endAnim.begin();
				beginAnim.end();
				singleLoadDlg.beginSingleMission();
				getButton( who )->press( 0 );
			}
			break;

		case MM_MSG_LEGAL:
			{
				bLegal = 1;
				// may need to set the text here
				if ( !LogisticsLegalDialog::instance() )
				{
					FullPathFileName path;
					path.init( artPath, "mcl_dialoglegal", ".fit" );
					FitIniFile file;
					file.open( path );
					LogisticsLegalDialog::init( file );
				}
				LogisticsLegalDialog::instance()->setText( IDS_DIALOG_OK,
						IDS_DIALOG_OK, IDS_DIALOG_OK );
				//Needs to be this long for LOC!
				// -fs
				char realText[2048];
				cLoadString(IDS_LAWYER_BABBLE, realText, 2047 );
				char lawyerBabble[2048];
				unsigned long pIDLen = 64;
				char pID[64];
				sprintf( pID, "INVALID ID" );
				gos_LoadDataFromRegistry("PID", pID, &pIDLen);
				sprintf( lawyerBabble, realText, pID );
				LogisticsLegalDialog::instance()->setText( lawyerBabble );
				LogisticsLegalDialog::instance()->begin();
				LogisticsLegalDialog::instance()->setFont( IDS_LAWYER_BABBLE_FONT );				
				getButton( who )->press( 0 );
			}
			break;
		default:
			break;
	}

	return 0;
}

void MainMenu::skipIntro()
{
	if ( introMovie )
	{
		introMovie->stop();
		delete introMovie;
		introMovie = NULL;

	}
}

void MainMenu::update()
{

	if ( bDrawBackground || MPlayer || LogisticsData::instance->isSingleMission() )
	{
		getButton( MM_MSG_SAVE )->disable( true );
	}
	else
		getButton( MM_MSG_SAVE )->disable( false );

	//getButton( MM_MSG_MULTIPLAYER )->disable( true );

	if ( introMovie )
	{
		userInput->mouseOff();

		if (userInput->getKeyDown(KEY_SPACE) || userInput->getKeyDown(KEY_ESCAPE) || userInput->getKeyDown(KEY_LMOUSE))
		{
			introMovie->stop();
		}

		bool result = introMovie->update();
		if (result)
		{
			
			//Movie's Over.
			//Whack it.
			delete introMovie;
			introMovie = NULL;
		}

		return;
	}

	if (!musicStarted)
	{
		musicStarted = true;
		soundSystem->setMusicVolume( prefs.MusicVolume );
		soundSystem->playDigitalMusic(tuneId);
	}

	if ( endAnim.isDone() )
	{
		status = endResult;
	}

	if ( bDrawMechlopedia )
	{
		mechlopedia->update();
		if ( mechlopedia->getStatus() == NEXT )
		{
			beginFadeIn( 0 );
			bDrawMechlopedia = 0;
			if ( !bDrawBackground )
				status = NEXT;
		}
		return;
	}

	if ( bOptions )
	{
		OptionsScreenWrapper::status_type result = optionsScreenWrapper->update();
		if (result == OptionsScreenWrapper::opt_DONE)
		{
			optionsScreenWrapper->end();
			bOptions = 0;
		}

		return;
	}

	if ( (bSave || bLoad || bLoadCampaign) && endAnim.isDone() )
	{
		LogisticsSaveDialog::instance()->update();

		if ( LogisticsSaveDialog::instance()->getStatus() == LogisticsScreen::YES 
			&& LogisticsSaveDialog::instance()->isDone() )
		{
			
			char name[1024];
			strcpy( name, savePath );
			strcat( name, LogisticsSaveDialog::instance()->getFileName() );
			int index = strlen( name ) - 4;
			if ( stricmp( &name[index], ".fit" ) !=0 ) 
				strcat( name, ".fit" );

			
			FitIniFile file;
			if ( bSave )
			{
				// make sure the save game directory exists, if not create it
				CreateDirectory( savePath, NULL );

				if ( NO_ERR != file.createWithCase( name ) )
				{
					char errorStr[1024];
					sprintf( errorStr, "couldn't open the file %s", name );
					Assert( 0, 0, errorStr );
				}
				else
				{
					LogisticsData::instance->save( file );
					LogisticsSaveDialog::instance()->end();
					file.close();
				}
				bSave = bLoad = 0;
				status = NEXT;
				

			}
			else if ( bLoadCampaign )
			{
				LogisticsData::instance->startNewCampaign( LogisticsSaveDialog::instance()->getFileName());
				status = endResult = RESTART;
//				background.beginFadeOut( 1.0f );
//				beginFadeOut( 1.0f );
				bLoadCampaign = 0;
			}
			else
			{
				if ( NO_ERR != file.open( name ) )
				{
					char errorStr[1024];
					sprintf( errorStr, "couldn't open the file %s", name );
					Assert( 0, 0, errorStr );
				}
				else
					LogisticsData::instance->load( file );
				LogisticsSaveDialog::instance()->end();
				bSave = bLoad = 0;
				status = RESTART;
				file.close();

			}
		}
		else if ( LogisticsSaveDialog::instance()->getStatus() == LogisticsScreen::NO &&
			LogisticsSaveDialog::instance()->isDone())
		{
			LogisticsSaveDialog::instance()->end();
			bSave = bLoad = bLoadCampaign = 0 ;
			if ( !bDrawBackground )
				status = NEXT;
			else
			{
				beginAnim.begin();
				endAnim.end();
			}
		}
		return;
	}
	else if ( bLoadSingle && endAnim.isDone())
	{
		singleLoadDlg.update();
		if ( singleLoadDlg.isDone() )
		{
			if ( singleLoadDlg.getStatus() == YES )
			{
				const char* pName = singleLoadDlg.getMapFileName();
				if (pName)
				{
					LogisticsData::instance->setSingleMission( pName );
					status = SKIPONENEXT;
				}
			}

			bLoadSingle = 0;
			beginAnim.begin();
			endAnim.end();
		}
	}

	else if ( promptToQuit )
	{
		LogisticsOKDialog::instance()->update();
		{
			if ( LogisticsOKDialog::instance()->getStatus() == LogisticsScreen::YES )
			{
				soundSystem->playDigitalSample( LOG_EXITGAME );
				gos_TerminateApplication();
				promptToQuit = 0;

			}
			else if ( LogisticsOKDialog::instance()->getStatus() == LogisticsScreen::NO)
			{
				if ( LogisticsOKDialog::instance()->isDone() )
					promptToQuit = 0;
			}

			

		}
	}
	else if ( bLegal )
	{
		LogisticsLegalDialog::instance()->update();
		if ( LogisticsLegalDialog::instance()->isDone() )
		{
			LogisticsLegalDialog::instance()->end();
			bLegal = 0;
		}
	}
	else if ( bHostLeftDlg )
	{
		LogisticsOneButtonDialog::instance()->update();
		if ( LogisticsOneButtonDialog::instance()->isDone() )
		{
			LogisticsOneButtonDialog::instance()->end();
			bHostLeftDlg = 0;
		}

		if ( MPlayer ) // has to be done, but can't be done when initialized
		{
			MPlayer->closeSession();
			delete MPlayer;
			MPlayer = NULL;
		}
	}
	else if ( promptToDisconnect )
	{
		LogisticsOKDialog::instance()->update();
		if ( LogisticsOKDialog::instance()->isDone() )
		{
			if ( YES == LogisticsOKDialog::instance()->getStatus() )
			{
				if ( MPlayer )
				{
					MPlayer->closeSession();
					delete MPlayer;
					MPlayer = NULL;
				}
				long oldRes = endResult;
				endResult = 0;

				handleMessage( oldRes, oldRes );

				setDrawBackground( true );
			}
			else
				handleMessage( NEXT, NEXT );
			
			promptToDisconnect = 0;
		}
	}
	else
	{
		if ( bDrawBackground  )
		{
			if ( !intro.animObjects[0].isDone() )
			{
				intro.update();
				background.update();
				if (userInput->getKeyDown(KEY_ESCAPE) || (Environment.Renderer == 3))
				{
					introOver = true;
					userInput->mouseOn();
					soundSystem->playDigitalSample( LOG_MAINMENUBUTTON );

				}
				else if ( !introOver )
					return;
			}
			else
			{
				background.update();
				if ( !introOver )
					soundSystem->playDigitalSample( LOG_MAINMENUBUTTON );

				introOver = true;
				userInput->mouseOn();

			}
		}

		beginAnim.update();
		endAnim.update();

		LogisticsScreen::update();
		if ( (!bLoadSingle) && userInput->isLeftClick() && !inside( userInput->getMouseX(), userInput->getMouseY() ) )
		{
			handleMessage( 0, MM_MSG_RETURN_TO_GAME );
		}
	}
}

void MainMenu::render()
{

	if (introMovie)
	{
		introMovie->render();
		return;
	}
	if ( bDrawMechlopedia && (fadeTime > fadeOutTime || !fadeOutTime) )
	{
		mechlopedia->render();
		return;
	}

	
	if ( bOptions )
	{
		optionsScreenWrapper->render();
		return;
	}

	//DO NOT play the splash screen animation in software.
	// WOW does it beat up the framerate!
	float xDelta = 0.f;
	float yDelta = 0.f;  
	long color = 0xff000000;

	if (Environment.Renderer != 3)
	{

		if ( beginAnim.isAnimating() && !beginAnim.isDone() )
		{
			xDelta = beginAnim.getXDelta();
			yDelta = beginAnim.getYDelta();

			float time = beginAnim.getCurrentTime();
			float endTime = beginAnim.getMaxTime();
			if ( endTime )
			{
				color = interpolateColor( 0x00000000, 0x7f000000, time/endTime );

			}
		}

		else if (endAnim.isAnimating() /*&& !endAnim.isDone()*/)
		{
			xDelta = endAnim.getXDelta();
			yDelta = endAnim.getYDelta();

			float time = endAnim.getCurrentTime();
			float endTime = endAnim.getMaxTime();
			if ( endTime && (time <= endTime))
			{
				color = interpolateColor( 0x7f000000, 0x00000000, time/endTime );
			}
		}

		GUI_RECT rect = { 0, 0, Environment.screenWidth, Environment.screenHeight };
		drawRect( rect, color );

		if ( bDrawBackground )
		{
			background.render();
			intro.render();
			if ( !intro.animObjects[0].isDone() && !introOver && !bHostLeftDlg )
				return;


		}
	}
	else
	{
		GUI_RECT rect = { 0, 0, Environment.screenWidth, Environment.screenHeight };
		drawRect( rect, color );
	}

	if ( !xDelta && !yDelta )
	{
		drawShadowText( 0xffc66600, 0xff000000, textObjects[1].font.getTempHandle(), 
			textObjects[1].globalX(), textObjects[1].globalTop(),
			textObjects[1].globalRight(), textObjects[1].globalBottom(),
			true, textObjects[1].text, false, textObjects[1].font.getSize(), 1, 1 );
	}

	textObjects[1].showGUIWindow( false );

	
	if ( (!bSave && !bLoad && !bLoadSingle && !bLoadCampaign) || (!endAnim.isDone() && endResult != RESTART ) )	
		LogisticsScreen::render( xDelta, yDelta );
	else if ( bLoadSingle )
		singleLoadDlg.render();
	else
		LogisticsSaveDialog::instance()->render();
 
	if ( promptToQuit || promptToDisconnect )
	{
		LogisticsOKDialog::instance()->render();
	}
	if ( bLegal )
	{
		LogisticsLegalDialog::instance()->render();
	}
	if ( bHostLeftDlg )
	{
		LogisticsOneButtonDialog::instance()->render();
	}



	
}

void MainMenu::setHostLeftDlg( const char* playerName )
{
	char leaveStr[256];
	char formatStr[256];

	cLoadString( IDS_PLAYER_LEFT, leaveStr, 255 );
	sprintf( formatStr, leaveStr, playerName );

	LogisticsOneButtonDialog::instance()->setText( IDS_PLAYER_LEFT,
					IDS_DIALOG_OK, IDS_DIALOG_OK );
	LogisticsOneButtonDialog::instance()->setText( formatStr );

	if ( MPlayer && MPlayer->playerInfo[MPlayer->commanderID].booted )
	{
		LogisticsOneButtonDialog::instance()->setText( IDS_MP_PLAYER_KICKED,
					IDS_DIALOG_OK, IDS_DIALOG_OK );

	}
	LogisticsOneButtonDialog::instance()->begin();
	bHostLeftDlg = true;

}




//*************************************************************************************************
// end of file ( MainMenu.cpp )
